﻿/************************************************************************
     Main File:

     File:        SJCNoise.cpp

     Author:     
                  Steven Chenney, schenney@cs.wisc.edu

     Modifier    
                  Yu-Chi Lai, yu-chi@cs.wisc.edu
  
     Comment:     
     
     Contructor:
                 

     Function:
  
************************************************************************/


#include <SJCNoise.h>


const uint PERM_SIZE = 256;
const uint PERM_ARRAY[512] = {
  75,
  119,
  231,
  7,
  29,
  253,
  163,
  45,
  81,
  134,
  31,
  66,
  138,
  169,
  246,
  111,
  62,
  102,
  103,
  232,
  17,
  48,
  243,
  73,
  158,
  123,
  222,
  78,
  40,
  187,
  197,
  16,
  20,
  166,
  219,
  193,
  168,
  178,
  114,
  133,
  181,
  64,
  201,
  140,
  254,
  32,
  237,
  139,
  46,
  180,
  153,
  0,
  249,
  80,
  251,
  234,
  101,
  165,
  25,
  255,
  2,
  247,
  209,
  28,
  30,
  137,
  86,
  8,
  252,
  36,
  90,
  183,
  235,
  127,
  228,
  67,
  22,
  110,
  105,
  150,
  108,
  14,
  155,
  95,
  204,
  190,
  151,
  27,
  128,
  84,
  87,
  170,
  24,
  212,
  130,
  113,
  94,
  142,
  79,
  13,
  4,
  194,
  9,
  112,
  241,
  99,
  159,
  100,
  240,
  213,
  125,
  185,
  117,
  77,
  55,
  198,
  229,
  203,
  47,
  126,
  238,
  156,
  129,
  5,
  61,
  143,
  248,
  124,
  179,
  141,
  135,
  85,
  91,
  172,
  72,
  244,
  230,
  154,
  227,
  147,
  200,
  152,
  50,
  70,
  145,
  217,
  51,
  211,
  189,
  199,
  39,
  188,
  118,
  122,
  206,
  89,
  97,
  15,
  104,
  96,
  26,
  160,
  37,
  106,
  59,
  98,
  23,
  53,
  19,
  69,
  207,
  68,
  92,
  182,
  38,
  233,
  242,
  42,
  52,
  88,
  171,
  215,
  245,
  157,
  56,
  210,
  220,
  196,
  250,
  12,
  6,
  54,
  65,
  107,
  35,
  49,
  82,
  221,
  3,
  146,
  225,
  116,
  186,
  214,
  164,
  120,
  205,
  76,
  149,
  60,
  162,
  191,
  121,
  1,
  33,
  10,
  136,
  83,
  43,
  239,
  184,
  202,
  195,
  208,
  41,
  131,
  226,
  34,
  176,
  109,
  174,
  218,
  58,
  192,
  44,
  175,
  236,
  18,
  57,
  216,
  173,
  63,
  167,
  21,
  144,
  132,
  93,
  115,
  224,
  74,
  71,
  148,
  11,
  177,
  161,
  223,
  75,
  119,
  231,
  7,
  29,
  253,
  163,
  45,
  81,
  134,
  31,
  66,
  138,
  169,
  246,
  111,
  62,
  102,
  103,
  232,
  17,
  48,
  243,
  73,
  158,
  123,
  222,
  78,
  40,
  187,
  197,
  16,
  20,
  166,
  219,
  193,
  168,
  178,
  114,
  133,
  181,
  64,
  201,
  140,
  254,
  32,
  237,
  139,
  46,
  180,
  153,
  0,
  249,
  80,
  251,
  234,
  101,
  165,
  25,
  255,
  2,
  247,
  209,
  28,
  30,
  137,
  86,
  8,
  252,
  36,
  90,
  183,
  235,
  127,
  228,
  67,
  22,
  110,
  105,
  150,
  108,
  14,
  155,
  95,
  204,
  190,
  151,
  27,
  128,
  84,
  87,
  170,
  24,
  212,
  130,
  113,
  94,
  142,
  79,
  13,
  4,
  194,
  9,
  112,
  241,
  99,
  159,
  100,
  240,
  213,
  125,
  185,
  117,
  77,
  55,
  198,
  229,
  203,
  47,
  126,
  238,
  156,
  129,
  5,
  61,
  143,
  248,
  124,
  179,
  141,
  135,
  85,
  91,
  172,
  72,
  244,
  230,
  154,
  227,
  147,
  200,
  152,
  50,
  70,
  145,
  217,
  51,
  211,
  189,
  199,
  39,
  188,
  118,
  122,
  206,
  89,
  97,
  15,
  104,
  96,
  26,
  160,
  37,
  106,
  59,
  98,
  23,
  53,
  19,
  69,
  207,
  68,
  92,
  182,
  38,
  233,
  242,
  42,
  52,
  88,
  171,
  215,
  245,
  157,
  56,
  210,
  220,
  196,
  250,
  12,
  6,
  54,
  65,
  107,
  35,
  49,
  82,
  221,
  3,
  146,
  225,
  116,
  186,
  214,
  164,
  120,
  205,
  76,
  149,
  60,
  162,
  191,
  121,
  1,
  33,
  10,
  136,
  83,
  43,
  239,
  184,
  202,
  195,
  208,
  41,
  131,
  226,
  34,
  176,
  109,
  174,
  218,
  58,
  192,
  44,
  175,
  236,
  18,
  57,
  216,
  173,
  63,
  167,
  21,
  144,
  132,
  93,
  115,
  224,
  74,
  71,
  148,
  11,
  177,
  161,
  223
};


//*****************************************************************************
//
//
// *
//=============================================================================
float SJCNoise::
Eval(const float x, const float y, const float z)
//=============================================================================
{
  int	  ix = (int)floor(x);
  float   dx = x - ix;
  int	  iy = (int)floor(y);
  float   dy = y - iy;
  int	  iz = (int)floor(z);
  float   dz = z - iz;
  
  ix &= ( PERM_SIZE - 1 );
  iy &= ( PERM_SIZE - 1 );
  iz &= ( PERM_SIZE - 1 );
  
  float   w000 = Grad(ix, iy, iz, dx, dy, dz);
  float   w010 = Grad(ix, iy+1, iz, dx, dy-1.0f, dz);
  float   w100 = Grad(ix+1, iy, iz, dx-1.0f, dy, dz);
  float   w110 = Grad(ix+1, iy+1, iz, dx-1.0f, dy-1.0f, dz);
  float   w001 = Grad(ix, iy, iz+1, dx, dy, dz-1.0f);
  float   w011 = Grad(ix, iy+1, iz+1, dx, dy-1.0f, dz-1.0f);
  float   w101 = Grad(ix+1, iy, iz+1, dx-1.0f, dy, dz-1.0f);
  float   w111 = Grad(ix+1, iy+1, iz+1, dx-1.0f, dy-1.0f, dz-1.0f);
  
  float   ux = NoiseWeight(dx);
  float   uy = NoiseWeight(dy);
  float   uz = NoiseWeight(dz);
  
  float   x00 = ( 1 - ux ) * w000 + ux * w100;
  float   x10 = ( 1 - ux ) * w010 + ux * w110;
  float   x01 = ( 1 - ux ) * w001 + ux * w101;
  float   x11 = ( 1 - ux ) * w011 + ux * w111;
  float   y0 = ( 1 - uy ) * x00 + uy * x10;
  float   y1 = ( 1 - uy ) * x01 + uy * x11;
  return ( 1 - uz ) * y0 + uz * y1;
}

//*****************************************************************************
//
//
// *
//=============================================================================
float SJCNoise::
Evaluate(const float x, const float y, const float z,
	 const int octaves, const float scale)
//=============================================================================
{
  float   result = 0.0;
  float   cumul_scale = 1.0f;
  for ( int i = 1 ; i <= octaves ; i++ )   {
    result += cumul_scale * Eval(i * x, i * y, i * z);
    cumul_scale *= scale;
  }

  return result;
}


